package com.zhousb.deviceManager.service.impl;

import com.zhousb.deviceManager.common.Constants;
import com.zhousb.deviceManager.model.entity.SysRole;
import com.zhousb.deviceManager.model.vo.AuthVo;
import com.zhousb.deviceManager.model.dto.LoginDto;
import com.zhousb.deviceManager.model.entity.SysUser;
import com.zhousb.deviceManager.exception.CustomerException;
import com.zhousb.deviceManager.security.JwtUser;
import com.zhousb.deviceManager.service.LoginService;
import com.zhousb.deviceManager.service.SysUserService;
import com.zhousb.deviceManager.utils.JwtUtil;
import com.zhousb.deviceManager.utils.NetUtils;
import com.zhousb.deviceManager.utils.RedisUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
public class LoginServiceImpl implements LoginService {
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private SysUserService sysUserService;
    @Resource
    private JwtUtil jwtUtil;
    @Resource
    private RedisUtil redisUtil;

    @Override
    public AuthVo login(LoginDto dto) {
        Authentication authentication;
        try {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(dto.getUsername(), dto.getPassword());
            authentication = authenticationManager.authenticate(authenticationToken);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new CustomerException("用户名/密码错误");
        }
        SecurityContextHolder.getContext().setAuthentication(authentication);
        JwtUser jwtUser = (JwtUser) authentication.getPrincipal();
        checkLock(jwtUser.getIsLock());
        SysUser sysUser = sysUserService.getById(jwtUser.getUserId());
        sysUser.setLastLoginTime(LocalDateTime.now())
                .setLastLoginIp(NetUtils.getRemoteIpAddr(getServletRequest()));
        sysUserService.updateUser(sysUser);
        return getAuthVo(sysUser);
    }

    private void checkLock(Integer isLock) {
        if (isLock != null && isLock == 1) {
            throw new CustomerException("用户已锁定");
        }
    }

    private HttpServletRequest getServletRequest() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert servletRequestAttributes != null;
        return servletRequestAttributes.getRequest();
    }

    private AuthVo getAuthVo(SysUser sysUser) {
        List<SysRole> roles = sysUserService.listRoleByUserId(sysUser.getId());
        Set<SysRole> roleSet = new HashSet<>(roles);
        JwtUser user = new JwtUser(sysUser.getId(), sysUser.getUserName(), sysUser.getPassword(),
                roleSet, sysUser.getRealName(), sysUser.getUserTel(),sysUser.getTenantId());
        AuthVo authVo = new AuthVo();
        authVo.setUser(user)
                .setAccessToken(jwtUtil.generateToken(user.getUserId(), user.getUsername(), user.getRealName(), user.getUserTel()));
        redisUtil.set("token:" + user.getUserId(), authVo, Constants.HOUR_24);
        return authVo;
    }
}
